<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Gemini Chat App</title>
    <script type="module">
        import { GoogleGenerativeAI } from "https://esm.run/@google/generative-ai";
        import { marked } from "https://esm.run/marked";

        let chat;
        let currentModel = "gemini-1.5-pro";
        let chatHistory = [];

        function getApiKey() {
            let apiKey = localStorage.getItem("GEMINI_API_KEY");
            if (!apiKey) {
                apiKey = prompt("Please enter your Gemini API key:");
                if (apiKey) {
                    localStorage.setItem("GEMINI_API_KEY", apiKey);
                }
            }
            return apiKey;
        }

        async function getGenerativeModel(params) {
            const API_KEY = getApiKey();
            const genAI = new GoogleGenerativeAI(API_KEY);
            return genAI.getGenerativeModel(params);
        }

        async function initChat() {
            try {
                const model = await getGenerativeModel({ model: currentModel });
                chat = model.startChat({
                    history: chatHistory,
                });
                displayMessage("System", `Chatting with ${currentModel}`);
            } catch (error) {
                displayError("Failed to initialize chat: " + error.message);
            }
        }

        async function sendMessage() {
            const userInput = document.getElementById("user-input");
            const message = userInput.value.trim();
            if (message) {
                displayMessage("You", message);
                userInput.value = "";

                try {
                    const startTime = performance.now();
                    const result = await chat.sendMessageStream(message);
                    let fullResponse = "";
                    for await (const chunk of result.stream) {
                        const chunkText = chunk.text();
                        fullResponse += chunkText;
                        updateModelResponse(fullResponse);
                    }
                    const endTime = performance.now();
                    const duration = ((endTime - startTime) / 1000).toFixed(2);
                    
                    // Add the user's message and the model's response to chatHistory after the interaction
                    chatHistory.push({ role: "user", parts: [{ text: message }] });
                    chatHistory.push({ role: "model", parts: [{ text: fullResponse }] });
                    
                    let usage = (await result.response).usageMetadata;
                    console.log("Full result:", result);
                    updateUsageMetadata(usage);
                    updateDuration(duration);
                } catch (error) {
                    displayError("Error: " + error.message);
                }
            }
        }

        function displayMessage(sender, message) {
            const chatMessages = document.getElementById("chat-messages");
            const messageElement = document.createElement("div");
            messageElement.innerHTML = `<strong>${sender}:</strong> ${marked.parse(message)}`;
            chatMessages.appendChild(messageElement);
            chatMessages.scrollTop = chatMessages.scrollHeight;
        }

        function displayError(message) {
            const chatMessages = document.getElementById("chat-messages");
            const errorElement = document.createElement("div");
            errorElement.innerHTML = `<strong style="color: red;">Error:</strong> <span style="color: red;">${message}</span>`;
            chatMessages.appendChild(errorElement);
            chatMessages.scrollTop = chatMessages.scrollHeight;
        }

        function updateModelResponse(response) {
            const chatMessages = document.getElementById("chat-messages");
            let modelResponse = chatMessages.lastElementChild;
            if (!modelResponse || !modelResponse.querySelector("strong")?.textContent.includes("Model")) {
                modelResponse = document.createElement("div");
                modelResponse.innerHTML = "<strong>Model:</strong> ";
                chatMessages.appendChild(modelResponse);
            }
            modelResponse.innerHTML = `<strong>Model:</strong> ${marked.parse(response)}`;
            chatMessages.scrollTop = chatMessages.scrollHeight;
        }

        function updateUsageMetadata(metadata) {
            const usageMetadataElement = document.getElementById("usage-metadata");
            usageMetadataElement.textContent = JSON.stringify(metadata, null, 2);
        }

        function updateDuration(duration) {
            const durationElement = document.getElementById("api-duration");
            durationElement.textContent = `Last API call duration: ${duration} seconds`;
        }

        function changeModel() {
            const modelSelect = document.getElementById("model-select");
            currentModel = modelSelect.value;
            displayMessage("System", `Changing model to ${currentModel}. Reinitializing chat...`);
            chatHistory = []; // Clear history when changing models
            initChat();
        }

        function clearChat() {
            chatHistory = [];
            document.getElementById("chat-messages").innerHTML = "";
            document.getElementById("usage-metadata").textContent = "";
            document.getElementById("api-duration").textContent = "";
            initChat();
        }

        window.onload = () => {
            initChat();
            document.getElementById("send-button").addEventListener("click", sendMessage);
            document.getElementById("user-input").addEventListener("keypress", (e) => {
                if (e.key === "Enter") sendMessage();
            });
            document.getElementById("model-select").addEventListener("change", changeModel);
            document.getElementById("clear-button").addEventListener("click", clearChat);
        };
    </script>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
        }
        #chat-messages {
            height: 400px;
            overflow-y: auto;
            border: 1px solid #ccc;
            padding: 10px;
            margin-bottom: 10px;
        }
        #user-input {
            width: calc(100% - 140px);
            padding: 5px;
        }
        #send-button, #clear-button {
            width: 60px;
            padding: 5px;
        }
        #model-select {
            margin-bottom: 10px;
        }
        #usage-metadata {
            white-space: pre-wrap;
            font-family: monospace;
            background-color: #f0f0f0;
            padding: 10px;
            margin-top: 10px;
        }
        #api-duration {
            margin-top: 10px;
            font-weight: bold;
        }
    </style>
</head>
<body>
    <h1>Gemini Chat App</h1>
    <select id="model-select">
        <option value="gemini-2.5-flash">gemini-2.5-flash (default)</option>
        <option value="gemini-2.5-pro">gemini-2.5-pro</option>
        <option value="gemini-2.5-flash-lite-preview-06-17">gemini-2.5-flash-lite-preview-06-17</option>
        <option value="gemini-2.0-flash-exp">gemini-2.0-flash-exp</option>
        <option value="gemini-1.5-pro-latest">gemini-1.5-pro</option>
        <option value="gemini-1.5-flash-latest">gemini-1.5-flash</option>
        <option value="gemini-1.5-flash-8b-latest">gemini-1.5-flash-8b</option>
    </select>
    <div id="chat-messages"></div>
    <input type="text" id="user-input" placeholder="Type your message...">
    <button id="send-button">Send</button>
    <button id="clear-button">Clear</button>
    <div id="api-duration"></div>
    <pre id="usage-metadata"></pre>
</body>
</html>
